/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package poker.geneticAlgorithm;

import java.util.ArrayList;
import java.util.List;

/**
 * A Genetic Algorithm to evolve optimal weights for the poker player using
 * minimax.
 * 
 * May not be applicable to all GA applications... Only being written for this
 * application.
 * 
 * 
 * @author Benjamin L. Brodie <blbrodie@gmail.com>
 */
public class WeightsGA {
    
    private PopulationOfWeights population;
    private Selection<Individual<Double>> selector;
    private Crossover<Individual<Double>> crossover;
    private Mutation<Individual<Double>> mutation;
    private int totalEvaluations;
    
    
    
    public WeightsGA(PopulationOfWeights population, Selection<Individual<Double>> selector,
              Crossover<Individual<Double>> crossover, Mutation<Individual<Double>> mutation, int totalEvaluations){
        
        this.population = population;
        this.selector = selector;
        this.crossover = crossover;
        this.mutation = mutation;
        this.totalEvaluations = totalEvaluations;
    }
    
    
    public PopulationOfWeights run(){
        for (int i = 0; i < totalEvaluations; i++){
           
           
           List<Individual<Double>> winners = winnersOfTournaments();
           List<Individual<Double>> crossed = crossover.cross(winners);
           List<Individual<Double>> mutated = mutation.mutate(crossed);
           
           for (Individual<Double> individual : mutated){
               population.replaceRandomWith(individual);
           }
            
        }
        
        return population;
        
    }
    
    
    //returns the two individuals who won two tournaments, one for each tournament
    private List<Individual<Double>> winnersOfTournaments(){
        
        //compete the players
        Individual<Double> winner_1 = selector.selectFrom(selectCompetitors());
        Individual<Double> winner_2 = selector.selectFrom(selectCompetitors());
        
        List<Individual<Double>> winners = new ArrayList<Individual<Double>>();
        winners.add(winner_1);
        winners.add(winner_2);
        return winners;
        
    }
    
    
    //selectors the two competitors for one tournament
    private List<Individual<Double>> selectCompetitors(){
        
         //put random individuals in a list
            List<Individual<Double>> randomIndividuals = new ArrayList<Individual<Double>>();
            randomIndividuals.add(population.getRandomIndividual());
            randomIndividuals.add(population.getRandomIndividual());
            
         
            return randomIndividuals;
        
    }
    
    private void output(int i){
        System.out.print("Evaluation " + i + ": ");
        
        System.out.print(population);
    }
}
